
#include <BOpenGL>
#include "IAlgorithm.h"
#include "member_BParticle.h"
#include "member_BShape.h"

using namespace BWE;

member_BParticle::member_BParticle(BParticle* particle)
{
	boss = particle;
	size.set(1.0f, 1.0f);
	particleDuration = 10;
	emitterDuration = 10;
	dirty = false;
}
member_BParticle::~member_BParticle()
{

}
void member_BParticle::build(BMesh* mesh, const BSpace& space)
{
	m_space = space;
	const BVectorArray* vertices = mesh->vertices();
	if (const BFaceArray* faces = mesh->faces())
	{
		for (int i = 0; i < faces->size(); i++)
		{
			const BFace& face = faces->at(i);
			BVector va = vertices->at(face.a());
			BVector vb = vertices->at(face.b());
			BVector vc = vertices->at(face.c());
			Node& node = leafNodes.append();
			node.space.reset(va);
			node.space.expand(vb);
			node.space.expand(vc);
			node.center = node.space.center();
			node.index = i;
		}
	}
	treeNodes.resize(2 * leafNodes.size());
	lastIndex = 0;
	buildTree(0, leafNodes.size());
}
void member_BParticle::buildTree(int startIndex, int endIndex)
{
	Node& node = treeNodes[lastIndex];
	int numIndices = endIndex - startIndex;
	if (numIndices == 1)
	{
		node = leafNodes[startIndex];
		lastIndex++;
		return;
	}

	BVector means;
	for (int i = startIndex; i < endIndex; i++)
	{
		means += leafNodes[i].center;
	}
	means /= numIndices;

	BVector variance;
	for (int i = startIndex; i < endIndex; i++)
	{
		BVector diff2 = leafNodes[i].center - means;
		variance += diff2 * diff2;
	}
	variance /= numIndices - 1;

	int splitIndex = startIndex;
	{
		int axis = MaxAxis(variance);
		BReal splitValue = means[axis];
		for (int i = startIndex; i < endIndex; i++)
		{
			const BVector& center = leafNodes[i].center;
			if (center[axis] > splitValue)
			{
				leafNodes.swap(i, splitIndex);
				splitIndex++;
			}
		}
		int numBalanced = numIndices / 3;
		if (splitIndex <= (startIndex + numBalanced) || splitIndex >= (endIndex - 1 - numBalanced))
		{
			splitIndex = startIndex + (numIndices >> 1);
		}
	}

	node.space.min() = m_space.max();
	node.space.max() = m_space.min();
	for (int i = startIndex; i < endIndex; i++)
	{
		const BSpace& space = leafNodes[i].space;
		node.space.expand(space);
	}

	int curIndex = lastIndex++;
	buildTree(startIndex, splitIndex);
	buildTree(splitIndex, endIndex);
	node.index = curIndex - lastIndex;
}

void member_BParticle::overlapping(ITriangleCallback* callback, const BSpace& space) const
{
	m_processCount = 0;
	int index = 0;
	while (index < lastIndex)
	{
		const Node& node = treeNodes[index];
		bool overlapped = space.intersect(node.space);
		if (overlapped && node.index >= 0)
		{
			m_processCount++;
			//processNode(callback, node.index);
		}
		if (overlapped || node.index >= 0)
		{
			index++;
		}
		else
		{
			index -= node.index;
		}
	}
}
void member_BParticle::overlapping(ITriangleCallback* callback, const BLine& line) const
{
	m_processCount = 0;
	int index = 0;
	while (index < lastIndex)
	{
		const Node& node = treeNodes[index];
		bool overlapped = line.intersect(node.space);
		if (overlapped && node.index >= 0)
		{
			m_processCount++;
			//processNode(callback, node.index);
		}
		if (overlapped || node.index >= 0)
		{
			index++;
		}
		else
		{
			index -= node.index;
		}
	}
}
